import UIKit
import AssetsLibrary

@objc
protocol ImageContentViewControllerDelegate: NSObjectProtocol {
    optional func imageContentViewController(imageContentViewController: ImageContentViewController, photosAdded: [AlbumImage], selectedImagesData: [NSData], selectedImageSize: Int64)
}

// 间距
private let kMinimumSpacing: CGFloat = 1
// cell ID
private let kImagePickerCellID = "imagePicker"
// 删除照片之后返回刷新
private let kResponseNotificationRefreshImages = "kResponseNotificationRefreshImages"
// 选择最多图片在选择图片的提示
private let kMaxSelectedMessage = "系统最多选择%d张照片"
private let kMaxByteSizeMessage = "图片太大, 不能超过%d字节"
private let kNavigationBarMaxHeight: CGFloat = 64

class ImageContentViewController: UIViewController {
    // MARK: - 开放的属性
    
    // 最多选择的图片数量
    var maxSelectedCount = Int.max
    // 选择图片最大 10M
    var maxByteSize: Int64 = kMaxByteSize
    // cell 选中边框颜色
    var borderColor: UIColor?
    // cell 选中边上角label 填充颜色
    var fillLabelColor: UIColor?
    var perRowNumber = kNumberOfImagePerRow
    var leftButtonTitle: String?
    var rightButtonTitle: String?
    weak var pickerDelegate: ImageContentViewControllerDelegate?
    var groupType = ALAssetsGroupSavedPhotos
    // Cell 类型
    var type: ImagePickerType = .Default
    
    // 授权失败提示
    lazy var authorizationAlertView: UIAlertView = {
        let appName = NSBundle.appName
        let alertView = UIAlertView(title: "授权失败", message: "授权失败, 请在设备的\"设置-隐私-照片\"选项中，允许 \(appName) 访问你的手机相册", delegate: nil, cancelButtonTitle: "OK")
        return alertView
    }()
    
    // 选择超出范围提示
    lazy var maxSelectedAlertView: UIAlertView = {
        let message = String.init(format: kMaxSelectedMessage, self.maxSelectedCount)
        let alertView = UIAlertView(title: "警告", message: message, delegate: nil, cancelButtonTitle: "OK")
        return alertView
    }()
    
    // 图片太大
    lazy var maxByteSizeAlertView: UIAlertView = {
        let message = String.init(format: kMaxByteSizeMessage, self.maxByteSize)
        let alertView = UIAlertView(title: "警告", message: message, delegate: nil, cancelButtonTitle: "OK")
        return alertView
    }()
    
    private var imagePickerHelp: ImagePickerHelp?
    private var albumImages: [AlbumImage] = []
    private var selectedImages: [AlbumImage] = []
    private var selectedImagesData: [NSData] = []
    private var selectedImageSize: Int64 = 0
    
    // MARK: - 懒加载属性
    // 流布局
    private lazy var flowLayout: UICollectionViewFlowLayout = {
        let flowLayout = UICollectionViewFlowLayout()
        flowLayout.minimumInteritemSpacing = kMinimumSpacing
        flowLayout.minimumLineSpacing = kMinimumSpacing
        flowLayout.scrollDirection = .Vertical
        let cellHeightAndWidth = (UIScreen.screenWidth - (kMinimumSpacing * (CGFloat(self.perRowNumber) - 1.0))) / CGFloat(self.perRowNumber)
        flowLayout.itemSize = CGSizeMake(cellHeightAndWidth, cellHeightAndWidth)
        
        return flowLayout
    }()
    
    // collectionView
    private lazy var collectionView: UICollectionView = {
        let collectionView = UICollectionView(frame: mainScreenBounds, collectionViewLayout: self.flowLayout)
        collectionView.dataSource = self
        collectionView.delegate = self
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.backgroundColor = UIColor.whiteColor()
        collectionView.alwaysBounceVertical = true
        collectionView.contentInset = UIEdgeInsets(top: kNavigationBarMaxHeight, left: 0, bottom: 0, right: 0)
        
        return collectionView
    }()
    
    // 导航栏左侧按钮
    private lazy var leftBarButtonItem: UIBarButtonItem = {
        let leftBarButtonItem = UIBarButtonItem(title: self.leftButtonTitle, style: .Plain, target: self, action: #selector(ImageContentViewController.didTapCancel))
        return leftBarButtonItem
    }()
    
    // 导航栏右侧按钮
    private lazy var rightBarButtonItem: UIBarButtonItem = {
        let rightBarButtonItem = UIBarButtonItem(title: self.rightButtonTitle, style: .Plain, target: self, action: #selector(ImageContentViewController.didTapDone))
        return rightBarButtonItem
    }()
    
    // MARK: - 系统方法
    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        view.backgroundColor = UIColor.whiteColor()
        automaticallyAdjustsScrollViewInsets = false
        
        navigationItem.leftBarButtonItem = leftBarButtonItem
        navigationItem.rightBarButtonItem = rightBarButtonItem
        
        view.addSubview(collectionView)
        registerCollectionCell()
        
        weak var weakSelf = self
        imagePickerHelp = ImagePickerHelp(type: groupType, filter: ALAssetsFilter.allPhotos()) { (status, albums) in
            if !status {
                weakSelf?.authorizationAlertView.delegate = self
                weakSelf?.authorizationAlertView.show()
                return
            }
            
            weakSelf?.albumImages = albums[0].images
            weakSelf?.collectionView.reloadData()
            if weakSelf?.albumImages.count > 0 {
                weakSelf?.collectionView.scrollToItemAtIndexPath(NSIndexPath(forRow: weakSelf!.albumImages.count - 1, inSection: 0), atScrollPosition: .None, animated: false)
            }
        }
        
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(receiveNotificationRefreshPhotos(_:)), name: UIApplicationDidBecomeActiveNotification, object: nil)
    }
    
    func registerCollectionCell() {
        // Tag
        if (type == .Tag) {
            collectionView.registerClass(ImagePickerTagCell.self, forCellWithReuseIdentifier: kImagePickerCellID)
            return
        }
        
        // Check
        if (type == .Check) {
            collectionView.registerClass(ImagePickerCheckCell.self, forCellWithReuseIdentifier: kImagePickerCellID)
            return
        }
        
        // Default
        collectionView.registerClass(ImagePickerDefaultCell.self, forCellWithReuseIdentifier: kImagePickerCellID)
    }
    
    // MARK: - 控件方法
    func didTapCancel() {
//        dismissViewControllerAnimated(true, completion: nil)
        self.navigationController?.popViewControllerAnimated(true)
    }
    
    func didTapDone() {
        selectedImagesData = []
        selectedImageSize = 0
        getSelectedData()
        pickerDelegate?.imageContentViewController?(self, photosAdded: selectedImages, selectedImagesData: selectedImagesData, selectedImageSize: selectedImageSize)
    }
    
    private func getSelectedData() {
        for (_, selectedImage) in selectedImages.enumerate() {
            let data = UIImageJPEGRepresentation(selectedImage.thumbnail!, 1.0)!
            selectedImagesData.append(data)
            selectedImageSize = selectedImageSize + selectedImage.byteSize
        }
    }
    
    func receiveNotificationRefreshPhotos(result: NSNotification) {
        weak var weakSelf = self
        imagePickerHelp?.refreshImages(self.groupType, filter: ALAssetsFilter.allPhotos(), isSuccess: { (status, albums) in
            if !status {
                weakSelf?.authorizationAlertView.show()
                return
            }
            
            weakSelf?.selectedImages = []
            weakSelf?.selectedImagesData = []
            weakSelf?.selectedImageSize = 0
            weakSelf?.albumImages = albums[0].images
            weakSelf?.collectionView.reloadData()
        })
    }
    
    deinit {
         print("ImageContentViewController: deinit")
    }
    
    private func setupCollectionViewCellValue(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> ImagePickerBaseCell {
        // Tag
        if (type == .Tag) {
            let cell = collectionView.dequeueReusableCellWithReuseIdentifier(kImagePickerCellID, forIndexPath: indexPath) as! ImagePickerTagCell
            cell.borderColor = borderColor
            cell.fillLabelColor = fillLabelColor
            return cell
        }
        
        // Check
        if (type == .Check) {
            return collectionView.dequeueReusableCellWithReuseIdentifier(kImagePickerCellID, forIndexPath: indexPath) as! ImagePickerCheckCell
        }
        
        // Default
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(kImagePickerCellID, forIndexPath: indexPath) as! ImagePickerDefaultCell
        cell.borderColor = borderColor
        return cell
    }
}

// MARK: <UICollectionViewDataSource> Methods
extension ImageContentViewController: UICollectionViewDataSource {
    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return albumImages.count
    }
    
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let albumImage = albumImages[indexPath.row]
        if albumImage.isSelected {
            albumImage.selectedIndex = selectedImages.indexOf(albumImage)! + 1
        }
        let cell = setupCollectionViewCellValue(collectionView, cellForItemAtIndexPath: indexPath)
        cell.albumImage = albumImage
        
        return cell
    }
}

// MARK: <UICollectionViewDelegate> Methods
extension ImageContentViewController: UICollectionViewDelegate {
    func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        
        let selectedImage = albumImages[indexPath.row]
        let isContains = selectedImages.contains(selectedImage)

        if !isContains && selectedImages.count >= maxSelectedCount  {
            maxSelectedAlertView.show()
            return
        }
        
        if selectedImage.byteSize > maxByteSize {
            maxByteSizeAlertView.show()
            return
        }
        
        selectedImage.isSelected = !isContains
        if isContains {
            let index = selectedImages.indexOf(selectedImage)
            selectedImages.removeAtIndex(index!)
            collectionView.reloadData()
            return
        }
        
        selectedImages.append(selectedImage)
        collectionView.reloadData()
    }
}

// MARK: <UIAlertViewDelegate> Methods
extension ImageContentViewController: UIAlertViewDelegate {
    func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int) {
        didTapCancel()
    }
}
